from datetime import datetime
from typing import TypeVar, Generic, Dict, Any, Union

from tortoise.queryset import QuerySet

from .base_models import BaseModel
from .base_schemas import BaseFilterSchema

T = TypeVar("T", bound=BaseModel)
D = TypeVar("D", bound=BaseFilterSchema)


class BaseFilter(Generic[T]):

    @classmethod
    def filter(
        cls, queryset: QuerySet[T], filter_condition: Union[D, Dict[str, Any]]
    ) -> QuerySet[T]:
        filters = (
            filter_condition.model_dump(exclude_unset=True)
            if isinstance(filter_condition, BaseFilterSchema)
            else filter_condition
        )
        for key, value in filters.items():
            if value is not None:
                filter_method = getattr(cls, f"filter_{key}", None)
                if filter_method:
                    queryset = filter_method(queryset, value)
        return queryset

    @staticmethod
    def filter_active(queryset: QuerySet[T], value: bool) -> QuerySet[T]:
        return queryset.filter(active=value)

    @staticmethod
    def filter_created_between(
        queryset: QuerySet[T], value: list[datetime]
    ) -> QuerySet[T]:
        return queryset.filter(created_at__range=value)

    @staticmethod
    def filter_updated_between(
        queryset: QuerySet[T], value: list[datetime]
    ) -> QuerySet[T]:
        return queryset.filter(updated_at__range=value)
